package com.pmcc.core.web;

import com.pmcc.core.config.security.JwtAuthenticationRequest;
import com.pmcc.core.config.security.JwtTokenUtil;
import com.pmcc.core.entity.security.Role;
import com.pmcc.core.repository.EmployeeRepository;
import com.pmcc.core.service.JwtAuthenticationResponse;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mobile.device.Device;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Controller
public class AuthenticationRestController {

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private UserDetailsService userDetailsService;

    @Autowired
    private EmployeeRepository employeeRepository;

    @Autowired
    private JwtTokenUtil jwtTokenUtil;

    @ApiOperation(value = "统一登录接口", notes = "返回的jwtToken要放在请求头当中")
    @PostMapping(value = "${jwt.route.authentication.path}")
    @ResponseBody
    public JwtAuthenticationResponse createAuthenticationToken(@RequestBody JwtAuthenticationRequest authenticationRequest, Device device) {
        // Perform the security
        Authentication authentication;
        try {
            authentication = authenticationManager.authenticate(
                    new UsernamePasswordAuthenticationToken(
                            authenticationRequest.getUsername(),
                            authenticationRequest.getPassword()
                    )
            );
        } catch (Exception e) {
            e.printStackTrace();
            return new JwtAuthenticationResponse();//登录失败
        }
        SecurityContextHolder.getContext().setAuthentication(authentication);
        // Reload password post-security so we can generate token
        final UserDetails userDetails = userDetailsService.loadUserByUsername(authenticationRequest.getUsername());
        List<Role> roles = employeeRepository.findByUsername(authenticationRequest.getUsername()).getRoleList();
        final String token = jwtTokenUtil.generateToken(userDetails, device);
        // Return the token
        return new JwtAuthenticationResponse(token, mapToRouteAuthorities(roles));
    }

    private static List<String> mapToRouteAuthorities(List<Role> roles) {
        log.info("roles:{}", roles);

        List<GrantedAuthority> grantedAuthorities = new ArrayList<>();
        for (Role role : roles) {
            log.info("role:{}", role.getCode());
            grantedAuthorities.add(new SimpleGrantedAuthority(role.getCode()));
        }
        return grantedAuthorities.stream().map(GrantedAuthority::getAuthority).collect(Collectors.toList());
    }

    /**
     * 登录页需要重新发起一次请求。需要返回index.html
     *
     * @return
     */
    @GetMapping(value = "/admin/user/login")
    public String getLoginPage() {
        return "admin/index.html";
    }
}
